import OSS from 'ali-oss'
import axios from 'axios'
import { getToken } from '@/utils/auth'

const region = 'oss-cn-beijing'
const bucket = 'zfatt'
const parallel = 3
const partSize = 1024 * 1024

let client = null
/**
 * 获取STS Token
 * 
 * accessKeyId
 * accessKeySecret
 * expiration
 * securityToken
 */
let credentials

async function loadCredential() {
	const {
		data
	} = await axios.get(`${window.config.VUE_APP_OSS_API}/api/sts`)
	credentials = data
}

// 创建OSS Client
async function initOSSClient() {
	await loadCredential()
	const {
		securityToken,
		accessKeyId,
		accessKeySecret
	} = credentials
	const info = {
		accessKeyId: accessKeyId,
		accessKeySecret: accessKeySecret,
		stsToken: securityToken,
		region: region,
		bucket: bucket
	}
	client = new OSS(info)
}

/**
 * 检查是否过期
 */
export const keepSTSAlive = async() => {
	if(!client) await initOSSClient()
	// 未过期
	if(new Date(credentials.expiration) > new Date()) return true
	client.cancel()
	await initOSSClient()
}

/**
 * 简单上传
 * @param {String} key oss key
 * @param {File} file 文件
 */
export async function put(key, file) {
	await keepSTSAlive();
	return client.put(key, file)
}
/**
 * 下载
 * @param {String} key oss key
 * @param {fileName} file 文件名称
 */
export async function downloadFile(fileUrl, fileName) {
	if(window.config.VUE_IS_LOCAL){
		var fileUrl = decodeURIComponent(fileUrl);
		var url = window.config.VUE_APP_BASE_API + '/api/course/downLoadFile?fileUrl=' + fileUrl;
		var downButton = document.createElement('a');
		downButton.href = url;
		downButton.download = fileName;
		downButton.click();
		window.URL.revokeObjectURL(url);
		return
	}else{
		await keepSTSAlive()
		var fileUrl = decodeURIComponent(fileUrl);
		var key = fileUrl;
		if(fileUrl.indexOf('http')!= -1){
			key = fileUrl.indexOf('https') == -1 ? fileUrl.split('http://zfatt.oss-cn-beijing.aliyuncs.com/')[1] : fileUrl.split('https://zfatt.oss-cn-beijing.aliyuncs.com/')[1];
		}
		const response = {
			'content-disposition': `attachment; filename=${encodeURIComponent(fileName)}`
		}
		var url = client.signatureUrl(key, {
			response
		})
		var downButton = document.createElement('a');
		downButton.href = url;
		downButton.download = fileName;
		downButton.click();
		window.URL.revokeObjectURL(url);
		return
	}
}
/**
 * 上传
 * @param {String} key 文件key
 * @param {File} file 文件
 * @param {Function} progress 进度回调函数
 */
export async function putProgress(key, file, progress) {
	if(window.config.VUE_IS_LOCAL) {
		var param = new FormData()
		param.append('path', key);
		param.append('file', file);
		return axios.post(window.config.VUE_APP_BASE_API + '/admin/user/uploadFile', param, {
			headers: {
				'Content-Type': 'multipart/form-data',
				'token':getToken(),
				'Authorization':'Bearer '+getToken(),
			},
			onUploadProgress: function(progressEvent) {
				let percent = progressEvent.loaded / progressEvent.total;
				if(progress){
					progress(percent);
				}
			}
		})
	} else {
		await keepSTSAlive()
		var param = {};
		if(progress) {
			param = {
				parallel: parallel,
				partSize: partSize,
				progress: async(p, ck) => {
					await keepSTSAlive()
					progress(p, ck)
				}
			}
		}
		return client.multipartUpload(key, file, param)
	}
}
/**
 * 分片上传
 * @param {String} key 文件key
 * @param {String|File} file 文件
 * @param {Function} progress 进度回调函数
 */
export async function createMultipartUpload(key, file, progress) {
	await keepSTSAlive()
	const param = {
		parallel: parallel,
		partSize: partSize,
		progress: async(p, ck) => {
			await keepSTSAlive()
			progress(p, ck)
		}
	}
	return client.multipartUpload(key, file, param)
}

/**
 * 断点续传
 * @param {String|File} file 文件
 * @param {Object} checkpoint 断点信息
 * @param {Function} progress 进度回调函数
 */
export async function resumeMultipartUpload(file, checkpoint, progress) {
	await keepSTSAlive()
	const param = {
		parallel: parallel,
		partSize: partSize,
		checkpoint: checkpoint,
		progress: async(p, ck) => {
			await keepSTSAlive()
			progress(p, ck)
		}
	}
	return client.multipartUpload(checkpoint.uploadId, file, param)
}

/**
 * 暂停上传
 */
export function suspendUpload() {
	if(client) client.cancel()
}

/**
 * 删除文件
 * @param {String} key 文件路径
 */
export const deleteObject = async key => {
	await keepSTSAlive()
	return client.delete(key)
}

/**
 * 删除多个文件
 * @param {Array} keys 文件路径
 */
export const deleteMulti = async keys => {
	await keepSTSAlive()
	return client.deleteMulti(keys)
}

/**
 * 列举指定前缀后的下一级文件及目录(100个)
 * @param {String} prefix oss 路径前缀
 */
export const listChild = async prefix => {
	await keepSTSAlive()
	return client.list({
		prefix: prefix,
		delimiter: '/'
	})
}

/**
 * 列举指定前缀后所有文件(100个)
 * @param {String} prefix oss 路径前缀
 */
export async function listObjects(prefix) {
	await keepSTSAlive()
	return client.list({
		prefix: prefix
	})
}